package org.brakepedal.server.support.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;

/**
 * Date: 2023/7/1 20:58
 *
 
 */
@Getter
@Slf4j
//@Configuration
//@ConfigurationProperties("spring.mvc.error-page")
public class Handle404Interceptor implements HandlerInterceptor, InitializingBean {

    private byte[] notFoundPageFileBytes;

    private String notFoundPagePath = "static/_index.html";

    /*private Consumer<HttpServletResponse> handler = (response_)->{
        if(Objects.isNull(notFoundPageFileBytes)) {
            try {
                notFoundPageFileBytes = Objects.requireNonNull(
                        this.getClass().getClassLoader().getResourceAsStream(this.notFoundPagePath)
                ).readAllBytes();
            } catch (IOException | NullPointerException e) {
                throw new RuntimeException("cannot found not-found-page from path '"+this.notFoundPagePath+"'");
            }
        }
        final Consumer<HttpServletResponse> processed = (response)->{
            if (response.getStatus() != HttpServletResponse.SC_NOT_FOUND) {
                return;
            }
            log.info("handle 404 page. it would send the file in classpath: {}",notFoundPagePath);
            try {
                try {
                    OutputStream ops = response.getOutputStream();
                    response.setContentType("text/html");
                    ops.write(notFoundPageFileBytes);
                } catch (IllegalStateException ignore){}
                response.setStatus(HttpServletResponse.SC_OK);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        };
        processed.accept(response_);
        handler = processed;
    };*/

    public Handle404Interceptor setNotFoundPagePath(String notFoundPagePath) {
        this.notFoundPagePath = notFoundPagePath;
        return this;
    }

    @Override
    public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) throws Exception {
//        response.sendRedirect("/_index.html");
//        response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
//        this.handler.accept(response);
        if (response.getStatus() != HttpServletResponse.SC_NOT_FOUND) {
            return;
        }
        try {
            try {
                OutputStream ops = response.getOutputStream();
                response.setContentType("text/html");
                ops.write(notFoundPageFileBytes);
            } catch (IllegalStateException ignore){}
            response.setStatus(HttpServletResponse.SC_OK);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /*
    * 在这个生命周期里, properties注入已完成, 所以notFoundPagePath不为空
    * */
    @Override
    public void afterPropertiesSet() throws Exception {
        try {
            notFoundPageFileBytes = Objects.requireNonNull(
                    this.getClass().getClassLoader().getResourceAsStream(this.notFoundPagePath)
            ).readAllBytes();
        } catch (IOException | NullPointerException e) {
            notFoundPageFileBytes = new byte[0];
            log.warn("cannot found not-found-page from path '"+this.notFoundPagePath+"'");
        }
    }
}
